package cz.cuni.mff.ufal.volk;


/**
 * Text in a natural language.
 * 
 * @author Bartłomiej Etenkowski
 */
public class Text implements Expression {
  
  private static final long serialVersionUID = 5570174413911512844L;

  /**
   * Constructs a Text object.
   * 
   * @param  language the language of the text
   * @param  text
   * 
   * @throws NullPointerException if the {@code text} parameter is {@code null}
   */
  public Text(String language, String text) {
    text.getClass(); // null check
    this.language = language;
    this.text = text;
  }
  
  private final String language;
  private final String text;

  /**
   * Gets the language of the text. 
   * @return the language of the text
   */
  @Override
  public String getLanguage() {
    return language;
  }
  
  /**
   * Gets the text.
   * @return the text
   */
  public String getText() {
    return text;
  }
  
  private boolean hashCodeCached = false;
  private int hashCode;
  
  /**
   * Returns a hash code for this {@code Text}.
   * @return a hash code for this object
   */
  public int hashCode() {
    if (!hashCodeCached) {
      int langCode = language == null ? 0 : language.hashCode();
      int textCode = text.hashCode();
      hashCode = 31 * langCode + textCode;
      hashCodeCached = true;
    }
    return hashCode;
  }
  
  /**
   * Compares this {@code Text} to the specified object. The result is {@code true} if and only
   * if the argument is not {@code null}, is a {@code Text} object in the same language
   * as this object (or both languages are {@code null}) and represents the same character
   * sequence as this object.
   * 
   * @param  obj the object to compare this {@code Text} against
   * @return {@code true} if {@code obj} represents an equivalent {@code Text}, {@code false}
   *         otherwise
   */
  public boolean equals(Object obj) {
    if (obj == this)
      return true;
    if (obj instanceof Text) {
      Text other = (Text)obj;
      if (this.language == null && other.language != null)
        return false;
      if (this.language != null && !this.language.equals(other.language))
        return false;
      // now we know that the languages are equal
      return text.equals(other.text);
    } else {
      return false;
    }
  }

}
